package com.loe.ktui.ui_custom

import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.HorizontalScrollView
import android.widget.LinearLayout
import androidx.core.view.forEach
import androidx.viewpager.widget.ViewPager
import com.loe.ktui.*
import com.loe.ktui.ui.KtViewPager
import com.loe.ktui.ui.UiGroup
import com.loe.ktui.util.UiShape

open class UiTab(id: String? = null) : UiGroup(id)
{
    override var width: Any? = MATCH_PARENT

    var divider: Any? = null
    var showDividers: Int? = null

    var onItemSelect: (KtTabView.(view: View, isSelect: Boolean) -> Unit)? = null
    fun onItemSelect(onItemSelect: KtTabView.(view: View, isSelect: Boolean) -> Unit)
    {
        this.onItemSelect = onItemSelect
    }

    var itemConvert: (KtTabView.(view: View, i: Int, bean: Any) -> Unit)? = null
    fun itemConvert(itemConvert: KtTabView.(view: View, i: Int, bean: Any) -> Unit)
    {
        this.itemConvert = itemConvert
    }

    var datas: List<Any>? = null

    var index: Int? = null
    var tabWidth: Any = MATCH_PARENT
    var isScroll: Boolean = false
    var scrollOffset: Double? = null
    var lineBg: Any? = null
    var lineHeight: Any = 2
    var linePaddingH: Any = 8
    var lineTransZ: Any = -0.1
    var lineGravity: Int = Gravity.BOTTOM
    var lineLen: Any = 24
    var isAuto = false
    var isWorm = false
    var isSmooth: Boolean? = null

    var viewPagerId: String? = null

    open fun initUI(context: Context, view: KtTabView)
    {
        super.initUI(context, view)

        if (isScroll) tabWidth = WRAP_CONTENT
        view.initLayout(tabWidth.dist)

        scrollOffset?.let { view.scrollOffset = it }

        divider?.let {
            if (it is UiShape)
            {
                view.tabLayout.dividerDrawable = it.createDrawable()
            } else
            {
                divider.toString().preLoadCallback(context) { drawable -> view.tabLayout.dividerDrawable = drawable }
            }
            view.tabLayout.showDividers = showDividers ?: LinearLayout.SHOW_DIVIDER_MIDDLE
        }

        onItemSelect?.let { view.onItemSelect = it }

        index?.let { view.index = it }

        lineBg?.let {
            view.linePaddingH = linePaddingH.dist
            view.lineLen = lineLen.dist
            view.lineTransZ = lineTransZ.distFloat
            view.lineGravity = lineGravity
            view.isAuto = isAuto
            view.isWorm = isWorm
            view.initLine(lineHeight.dist)
            view.tabLine?.let()
            { line ->
                if (it is UiShape)
                {
                    line.background = it.createDrawable()
                } else if (it is Int)
                {
                    line.setBackgroundColor(it)
                } else
                {
                    line.bg = it.toString()
                }
            }
        }

        isSmooth?.let { view.isSmooth = it }

        // 模板布局
        if (itemConvert != null)
        {
            if (childs.isNotEmpty() && !datas.isNullOrEmpty())
            {
                val ui = childs[0]
                if (!isScroll)
                {
                    ui.width = ui.width ?: 0
                }
                ui.height = ui.height ?: MATCH_PARENT
                datas?.forEachIndexed()
                { index, any ->
                    val v = ui.createView(context, view.tabLayout)
                    itemConvert?.let { view.it(v, index, any) }
                }
            }
        }
        // 固定布局
        else
        {
            // 递归子元素
            childs.forEach()
            {
                if (!isScroll)
                {
                    it.width = it.width ?: 0
                }
                it.height = it.height ?: MATCH_PARENT
                it.createView(context, view.tabLayout)
            }
        }
        view.initTabViews()
    }

    /** 创建view */
    override fun createView(context: Context, parent: ViewGroup?): View
    {
        val view = KtTabView(context)
        initUI(context, view)
        // viewPager
        viewPagerId?.let()
        { id ->
            delay()
            {
                if (parent != null)
                {
                    val viewpager = parent.findView<KtViewPager>(id)
                    view.setViewPager(viewpager)
                }
            }
        }
        return if (isScroll)
        {
            view.horizontalScrollView = HorizontalScrollView(context)
            view.horizontalScrollView?.scrollBarSize = 0
            view.horizontalScrollView?.addView(view, width.dist, height.dist)
            addToParent(parent, view.horizontalScrollView!!)
            view.horizontalScrollView!!
        } else
        {
            addToParent(parent, view)
            view
        }
    }

    fun createTabView(context: Context, parent: ViewGroup?): KtTabView = createView(context, parent) as KtTabView
}

fun Any.ui_Tab(id: String? = null, block: (UiTab.() -> Unit)? = null): UiTab
{
    val ui = UiTab(id)
    block?.let { ui.it() }
    if (this is UiGroup) addChild(ui)
    return ui
}

open class KtTabView : FrameLayout, View.OnClickListener
{
    constructor(context: Context) : super(context)
    {
        initXML()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    {
        initXML(attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        initXML(attrs)
    }

    private fun initXML(attrs: AttributeSet? = null)
    {
//        tabLine = View(context)
//        tabLine?.setBackgroundColor(KtColor.main)
//        addView(tabLine, MATCH_PARENT, px(2.0))
//        lineParams = tabLine?.layoutParams as LayoutParams?
    }

    internal fun initLayout(w: Int)
    {
        tabLayout = LinearLayout(context)
        tabLayout.orientation = HORIZONTAL
        addView(tabLayout, w, MATCH_PARENT)
    }

    internal fun initLine(h: Int)
    {
        tabLine = View(context)
        addView(tabLine, MATCH_PARENT, h)
        tabLine?.translationZ = lineTransZ
        lineParams = tabLine?.layoutParams as LayoutParams?
        lineParams?.gravity = lineGravity
        post { onScrolled(index, 0f) }
    }

    var horizontalScrollView: HorizontalScrollView? = null
        internal set

    lateinit var tabLayout: LinearLayout
        internal set
    var tabLine: View? = null
        internal set
    var viewPager: ViewPager? = null
        private set

    var scrollOffset: Double = 0.3

    /** line水平padding  */
    internal var linePaddingH = 0

    internal var lineLen = 0

    internal var lineTransZ = 0f

    internal var lineGravity: Int = Gravity.BOTTOM

    var isSmooth = true

    var isAuto = true

    var isWorm = true

    private var lineX = 0f

    private var lineW = 0f

    private var lineParams: LayoutParams? = null

    val list: ArrayList<View> = ArrayList()

    internal var onItemSelect: (KtTabView.(childView: View, isSelect: Boolean) -> Unit)? = null

//    var onItemSelected: ((i: Int) -> Unit)? = null

    fun initTabViews()
    {
        list.clear()
        tabLayout.forEach()
        { view ->
            addChild(view)
        }
        select(index)
    }

    private fun addChild(view: View)
    {
        list.add(view)
        view.setOnClickListener(this)
    }

    /** 当前选项下标 */
    var index = 0
        internal set

    override fun onClick(view: View)
    {
        list.forEachIndexed()
        { i, v ->
            val isSelect = v == view
            if (isSelect) this.index = i

            onItemSelect?.let { this.it(v, isSelect) }
        }

        viewPager?.setCurrentItem(index, isSmooth)
    }

    fun select(i: Int)
    {
        selectTab(i)
        viewPager?.setCurrentItem(i, isSmooth)
    }

    private fun selectTab(index: Int)
    {
        this.index = index
        list.forEachIndexed()
        { i, v ->
            onItemSelect?.let { this.it(v, index == i) }
        }
    }

    /**
     * tab切换滚动
     */
    open fun onScrolled(i: Int, scale: Float)
    {
        try
        {
            val nowView = list[i]
            val nextView = list[i + 1]
            // 蠕虫
            if (isWorm)
            {
                if (isAuto)
                {
                    if (scale < 0.5)
                    {
                        lineX = nowView.x
                        lineW = nowView.width + nextView.width * scale * 2
                    } else
                    {
                        val nW = nowView.width * (scale - 0.5f) * 2
                        lineX = nowView.x + nW
                        lineW = nowView.width + nextView.width - nW
                    }
                } else
                {
                    if (scale < 0.5)
                    {
                        lineX = nowView.x + (nowView.width - lineLen) / 2f
                        lineW = lineLen + (nextView.width + nowView.width) * scale
                    } else
                    {
                        lineX = nowView.x + (nowView.width - lineLen) / 2f + (nextView.width + nowView.width) * (scale - 0.5f)
                        lineW = lineLen + (nextView.width + nowView.width) * (1 - scale)
                    }
                }
            } else
            {
                if (isAuto)
                {
                    lineX = nowView.x + nowView.width * scale
                    lineW = nowView.width + (nextView.width - nowView.width) * scale
                } else
                {
                    lineX = nowView.x + (nowView.width - lineW) / 2 + (nextView.width + nowView.width) / 2f * scale
                    lineW = lineLen.toFloat()
                }
            }
            updateLine()
        } catch (e: Exception)
        {
        }
    }

    /**
     * 设置滑动位置
     */
    private fun updateLine()
    {
        val x: Float
        val w: Float
        if (isAuto)
        {
            x = lineX + linePaddingH + 1
            w = lineW - linePaddingH * 2
        } else
        {
            x = lineX + 2
            w = lineW
        }

        lineParams?.setMargins(x.toInt(), 0, 0, 0)
        lineParams?.width = w.toInt()
        tabLine?.layoutParams = lineParams
        // 滑动scrollview
        horizontalScrollView?.let()
        { scrollView ->
            val min = scrollView.width * scrollOffset

            val sx = (lineX - 2 - (scrollView.width - lineW) / 2).toInt()

            if (scrollView.scrollX - sx > min)
            {
                scrollView.smoothScrollTo((sx + min).toInt(), 0)
            }
            if (scrollView.scrollX - sx < -min)
            {
                scrollView.smoothScrollTo((sx - min).toInt(), 0)
            }
        }
    }

    fun setViewPager(viewPager: KtViewPager)
    {
        this.viewPager = viewPager
        viewPager.setCurrentItem(index, false)
        viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener
        {
            override fun onPageSelected(index: Int)
            {
                selectTab(index)
                this@KtTabView.index = index
            }

            override fun onPageScrolled(i: Int, scale: Float, arg2: Int)
            {
                onScrolled(i, scale)
            }

            override fun onPageScrollStateChanged(arg0: Int)
            {
            }
        })
    }
}